/*
主程序
代码的测试也暂时写在这里
*/
#include "FileUtil.hpp"
#include "JsonUtil.hpp"
#include "Config.hpp"
#include "DataManager.hpp"
#include "HotspotManager.hpp"
#include "Service.hpp"
#include "log.hpp"
#include <thread>
cloud::DataManager* dm;         // 用于管理数据
Log my_log;                     // 用于打印日志

// 测试获取文件属性功能
void testFileUtil(const std::string& s)
{
    cloud::FileUtil f(s);
    printf("文件UUID: %s\n", f.getUuid().c_str());
    printf("文件大小: %ld\n", f.getFileSize());
    printf("文件最后一次修改时间: %ld\n", f.getLastMTime());
    printf("文件最后一次访问时间: %ld\n", f.getLastATime());
    printf("获得一个路径最后文件的名称: %s\n", f.getFileName().c_str());
}

// 测试文件读写功能
void testFileUtil2(const std::string& fileName)
{
    cloud::FileUtil f(fileName);
    std::string s;
    f.getFullContent(&s);
    // std::cout << s;
    cloud::FileUtil of("writeTest.txt");        // 打开一个名为writeTest.txt的文件，没有则创建
    of.setContent(s);
}

// 测试解压缩
void testFileUtil3(const std::string& fileName)
{
    cloud::FileUtil f(fileName);
    std::string packName = fileName + ".lz";        // 压缩包的名字
    f.compresss(packName);
    std::string unPackName = "newname.cpp";         // 解压缩后创建文件的名字
    f.unCompress(unPackName);
}

// 测试目录操作
void testFileUtil4(const std::string& fileName)
{
    cloud::FileUtil f(fileName);
    f.createDir();      // 创建一个文件夹
    std::vector<std::string> array;
    f.scanDir(&array);
    // 打印目录下的文件内容
    for(const auto& e : array) {
        std::cout << e << '\n';
    }
}

// 测试JsonUtil
void testJsonUtil()
{
     /* 序列化 */
    std::string name = "zhangsan";
    int age = 20;
    int scores[] = {80, 90, 100};
    // 给数据对象类添加数据
    Json::Value value;
    value["name"] = name;
    value["age"] = age;
    value["score"].append(scores[0]);
    value["score"].append(scores[1]);
    value["score"].append(scores[2]);
    std::string str;
    cloud::JsonUtil::serialize(value, &str);
    printf("序列化结果:\n %s\n%s\n", str.c_str(), "========================================");

    Json::Value oValue;
    /* 反序列化, 将s反序列化*/
    cloud::JsonUtil::unserialize(str, &oValue);
    printf("反序列化结果: \nname: %s\nage: %d\n", 
            (oValue["name"].asString()).c_str(), oValue["age"].asInt());
    for(int i = 0; i < 3; ++i) {
        printf("成绩%d: %d\n", i, oValue["score"][i].asInt());
    }
}

// 测试Config.hpp
void testConfig()
{   
    cloud::Config* cof = cloud::Config::getInstance();
    // std::cout << cof->getServerIp() << '\n';
    // std::cout << cof->getServerPort() << '\n';
    // std::cout << cof->getHotTime() << '\n';
    // std::cout << cof->getDownPre() << '\n';
    // std::cout << cof->getRarSuf() << '\n';
    // std::cout << cof->getUlPath() << '\n';
    // std::cout << cof->getRarPath() << '\n';
    // std::cout << cof->getBackups() << '\n';
    // std::cout << "===================" << '\n';
    // std::cout << cof->getDbHost() << '\n';
    // std::cout << cof->getDbPort() << '\n';
    // std::cout << cof->getDbUser() << '\n';
    // std::cout << cof->getDbPasswd() << '\n';
    // std::cout << cof->getDbName() << '\n';

    cof->delInstance();
}

// 测试DataManager.hpp中BackupInfo的初始化
void testBackupInfo(const std::string& fileName)
{
    cloud::BackupInfo bi(fileName);
    std::cout << bi.isPacked << '\n';
    std::cout << bi.fileSz << '\n';
    std::cout << bi.lastMTime << '\n';
    std::cout << bi.lastATime << '\n';
    std::cout << bi.ulFilePath << '\n';
    std::cout << bi.rarFilePath << '\n';
    std::cout << bi.urlPath << '\n';
    /*
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ls 
    cloud  cloud.conf  Cloud.cpp  Config.hpp  DataManager.hpp  FileUtil.hpp  JsonUtil.hpp  makefile  test
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud Config.hpp 
    0
    3067
    1734863161
    1734863161
    ./files/Config.hpp
    ./rars/Config.hpp.lz
    /listShow/Config.hpp
    */
}

// 测试DataManager.hpp中BackupInfo的初始化2
void testBackupInfo2()
{
    cloud::BackupInfo bi("iii");
    if(bi.isOk()) {
        std::cout << bi.isPacked << '\n';
        std::cout << bi.fileSz << '\n';
        std::cout << bi.lastMTime << '\n';
        std::cout << bi.lastATime << '\n';
        std::cout << bi.ulFilePath << '\n';
        std::cout << bi.rarFilePath << '\n';
        std::cout << bi.urlPath << '\n';
    } else {
        std::cout << "not ok~\n";
    }
}

void printInfo(const cloud::BackupInfo& bi)
{
    std::cout << "====================================\n";
    std::cout << bi.isPacked << '\n';
    std::cout << bi.fileSz << '\n';
    std::cout << bi.ulFilePath << '\n';
    std::cout << bi.rarFilePath << '\n';
    std::cout << bi.urlPath << '\n';
    std::cout << bi.lastATime << '\n';
    std::cout << bi.lastMTime << '\n';
    std::cout << "====================================\n";
}

// 测试DataManager.hpp中DataManager的增查改功能
void testDataManager1()
{
    // 先增加两个文件, 以./Config.hpp和./DataManager.hpp为例
    // cloud::BackupInfo bi1("./Config.hpp");    
    // cloud::BackupInfo bi2("./DataManager.hpp");    
    cloud::DataManager dm;
    // dm.insertInfo(bi1);
    // dm.insertInfo(bi2);
    // std::cout << "插入文件成功(目前在内存的哈希表中...)\n";
    // 根据urlPath查看文件信息
    // std::cout << "根据urlPath查看文件Config.hpp信息\n";
    // cloud::BackupInfo t1;
    // dm.get1FromURL("/listShow/Config.hpp", &t1);
    // printInfo(t1);
    // 根据在服务器实际的文件名查看文件信息
    // std::cout << "根据服务器实际的文件名查看文件DataManager信息\n";
    // cloud::BackupInfo t2;
    // dm.get1FromPath("./files/DataManager.hpp", &t2);
    // printInfo(t2);
    // 修改文件信息, 这里修改bi1的一个属性
    // bi1.isPacked = true;
    // dm.updateInfo(bi1);
    // 查看所有文件的信息
    std::cout << "查看dm管理的所有文件的信息\n";
    std::vector<cloud::BackupInfo> arrays;
    dm.getAllInfo(&arrays);
    for(const auto &e : arrays) {
        printInfo(e);
    }
    /*
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud 
    插入文件成功(目前在内存的哈希表中...)
    根据urlPath查看文件Config.hpp信息
    ====================================
    0
    3067
    ./files/Config.hpp
    ./rars/Config.hpp.lz
    /listShow/Config.hpp
    ====================================
    根据服务器实际的文件名查看文件DataManager信息
    ====================================
    0
    4812
    ./files/DataManager.hpp
    ./rars/DataManager.hpp.lz
    /listShow/DataManager.hpp
    ====================================
    查看dm管理的所有文件的信息
    ====================================
    0
    4812
    ./files/DataManager.hpp
    ./rars/DataManager.hpp.lz
    /listShow/DataManager.hpp
    ====================================
    ====================================
    1
    3067
    ./files/Config.hpp
    ./rars/Config.hpp.lz
    /listShow/Config.hpp
    ====================================
    */
}

// 测试DataManager.hpp备份功能
void testStorage()
{
    // 先增加两个文件, 以./Config.hpp和./DataManager.hpp为例
    cloud::BackupInfo bi1("./Config.hpp");    
    cloud::BackupInfo bi2("./DataManager.hpp");    
    cloud::DataManager dm;
    dm.insertInfo(bi1);
    dm.insertInfo(bi2);
    std::cout << "插入文件成功(目前在内存的哈希表中...)\n";
    dm.strorageBackup();
    /*
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ cat backups.data 
[
	{
		"fileSz" : 5940,
		"isPacked" : false,
		"lastATime" : 1735040774,
		"lastMTime" : 1735040774,
		"rarFilePath" : "./rars/DataManager.hpp.lz",
		"ulFilePath" : "./files/DataManager.hpp",
		"urlPath" : "/listShow/DataManager.hpp"
	},
	{
		"fileSz" : 3067,
		"isPacked" : false,
		"lastATime" : 1735030412,
		"lastMTime" : 1734863161,
		"rarFilePath" : "./rars/Config.hpp.lz",
		"ulFilePath" : "./files/Config.hpp",
		"urlPath" : "/listShow/Config.hpp"
	}
]
    */
}

// 测试DataManager.hpp备份功能2
void testStorage2()
{
    cloud::BackupInfo bi1("Config.hpp");
    if(bi1.isOk() == false) {
        std::cout << "not ok~\n";
    } else{
        cloud::DataManager dm;
        dm.insertInfo(bi1);
        dm.strorageBackup();
    }
}

// 测试DataManager.hpp加载配置信息功能, 此时backups.data文件已经存在
void testDataManager2()
{
    cloud::DataManager dm;
    // 查看所有文件的信息
    std::cout << "查看dm管理的所有文件的信息\n";
    std::vector<cloud::BackupInfo> arrays;
    dm.getAllInfo(&arrays);
    for(const auto &e : arrays) {
        printInfo(e);
    }
    /*
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ ./cloud 
    查看dm管理的所有文件的信息
    ====================================
    0
    3067
    ./files/Config.hpp
    ./rars/Config.hpp.lz
    /listShow/Config.hpp
    ====================================
    ====================================
    0
    5940
    ./files/DataManager.hpp
    ./rars/DataManager.hpp.lz
    /listShow/DataManager.hpp
    ====================================
    */
}

// 热点管理功能
void hotspot()
{
    // todo: 多线程压缩, 线程池
    // 增加测试文件, 以./files/a.txt
    // cloud::BackupInfo bi1("./files/a.txt");     
    // cloud::DataManager dm;
    // dm.insertInfo(bi1);
    // dm.strorageBackup();
    cloud::HotspotManager hm;
    hm.runHotspotManager();
    /*lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ tree
    .
    ├── backups.data
    ├── cloud
    ├── cloud.conf
    ├── Cloud.cpp
    ├── Config.hpp
    ├── DataManager.hpp
    ├── files
    │   └── a.txt
    ├── FileUtil.hpp
    ├── HotspotManager.hpp
    ├── JsonUtil.hpp
    ├── makefile
    └── rars

    2 directories, 11 files
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ tree
    .
    ├── backups.data
    ├── cloud
    ├── cloud.conf
    ├── Cloud.cpp
    ├── Config.hpp
    ├── DataManager.hpp
    ├── files
    ├── FileUtil.hpp
    ├── HotspotManager.hpp
    ├── JsonUtil.hpp
    ├── makefile
    └── rars
        └── a.txt.lz

    2 directories, 11 files
    lyf@hcss-ecs-3db9:~/pro/pro24_12_18云备份$ cat backups.data 
    [
        {
            "fileSz" : 13,
            "isPacked" : true,
            "lastATime" : 1735110663,
            "lastMTime" : 1735110663,
            "rarFilePath" : "./rars/a.txt.lz",
            "ulFilePath" : "./files/a.txt",
            "urlPath" : "/listShow/a.txt"
        }
    ]
    */
}

// Service.hpp
void service()
{
    cloud::Service srv;
    srv.runService();
}

// int main(int argc, char* argv[])
// {
//     dm = new cloud::DataManager();
//     std::thread tHot(hotspot);
//     std::thread tSvr(service);
//     tHot.join();
//     tSvr.join();
//     // if(argc != 2) {
//     //     std::cerr << "usage error!\n"; 
//     //     return -1;
//     // }

//     // testFileUtil(argv[1]);
//     // testFileUtil2(argv[1]);
//     // testFileUtil3(argv[1]);
//     // testFileUtil4(argv[1]);
//     // testJsonUtil();
//     // testConfig();
//     // testBackupInfo(argv[1]);
//     // testBackupInfo2();
//     // testStorage();
//     // testStorage2();
//     // testDataManager2();
//     // testHotspot();
//     // testService1();
//     delete dm;
//     return 0;
// }

// 测试数据库功能1：插入数据
int testDataBase()
{
    // 先向哈希表中插入两个数据
    cloud::BackupInfo bi1("../Config.hpp");    
    cloud::BackupInfo bi2("../DataManager.hpp");    
    cloud::DataManager dm;
    dm.insertInfo(bi1);
    dm.insertInfo(bi2);
    std::cout << "插入文件成功(目前在内存的哈希表中...)\n";
    dm.strorageBackup();
}

// 测试数据库功能2: 查询数据
void testDataBase2()
{
    cloud::DataManager dm;
    // 查看所有文件的信息
    std::cout << "查看dm管理的所有文件的信息\n";
    std::vector<cloud::BackupInfo> arrays;
    dm.getAllInfo(&arrays);
    for(const auto &e : arrays) {
        printInfo(e);
    }
}

int main(int argc, char* argv[])
{
    try {
        dm = new cloud::DataManager();
        std::thread tHot(hotspot);
        std::thread tSvr(service);
        tHot.join();
        tSvr.join();
    } catch(const std::exception& e) {
        std::cerr << "Exception: " << e.what() << '\n';
    }
    return 0;
}